package com.ly.os;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * @Classname PhilosopherEatQuestionSemaphoreSemaphore
 * @Description TODO
 * @Date 2020/12/7 14:27
 * @Author 冷心影翼
 */
public class PhilosopherEatQuestionSemaphore {

	private Semaphore[] semaphoreArr = new Semaphore[5];

	private Semaphore leftCount = new Semaphore(4);

	public PhilosopherEatQuestionSemaphore() {
		for(int i=0;i<5;i++) {
			semaphoreArr[i] = new Semaphore(1);
		}
	}

	public void eatWithDeadLock() {
		for(int i=0;i<5;i++) {
			int finalI = i;

			new Thread(() -> {
				while (true) {
					try {

						semaphoreArr[finalI].acquire();
						semaphoreArr[(finalI+1)%5].acquire();

						System.out.println(finalI+"eat");

						semaphoreArr[finalI].release();
						semaphoreArr[(finalI+1)%5].release();
						Thread.yield();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}).start();
		}
	}

	public void eat() {
		for(int i=0;i<5;i++) {
			int finalI = i;
			new Thread(() -> {
				while (true) {
					try {
						leftCount.acquire();
						semaphoreArr[finalI].acquire();
						semaphoreArr[(finalI+1)%5].acquire();
						System.out.println(finalI+"eat");
						semaphoreArr[finalI].release();
						semaphoreArr[(finalI+1)%5].release();
						leftCount.release();
						Thread.yield();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}).start();
		}
	}

	public void eat2() {
		for(int i=0;i<5;i++) {
			int finalI = i;
			new Thread(() -> {
				while (true) {
					try {
						if(finalI%2 == 0) {
							semaphoreArr[finalI].acquire();
							semaphoreArr[(finalI+1)%5].acquire();
						}else {
							semaphoreArr[(finalI+1)%5].acquire();
							semaphoreArr[finalI].acquire();
						}
						System.out.println(finalI+"eat");
						semaphoreArr[finalI].release();
						semaphoreArr[(finalI+1)%5].release();
						leftCount.release();
						Thread.yield();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}).start();
		}
	}

	public void eat3() {
		for(int i=0;i<5;i++) {
			int finalI = i;
			new Thread(() -> {
				while (true) {
					try {
						semaphoreArr[finalI].tryAcquire(3, TimeUnit.SECONDS);
						semaphoreArr[(finalI+1)%5].tryAcquire(3,TimeUnit.SECONDS);

						System.out.println(finalI+"eat");
						semaphoreArr[finalI].release();
						semaphoreArr[(finalI+1)%5].release();
						leftCount.release();
						Thread.yield();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}

			}).start();
		}
	}


	public static void main(String[] args) {
		PhilosopherEatQuestionSemaphore PhilosopherEatQuestion = new PhilosopherEatQuestionSemaphore();
//		PhilosopherEatQuestion.eatWithDeadLock();
//		PhilosopherEatQuestion.eat();
//		PhilosopherEatQuestion.eat2();
//		PhilosopherEatQuestion.eat3();
	}
}

